#include"myshell.h"

#define none_refdir 0
#define input_refdir 1
#define output_refdir 2
#define append_refdir 3

int ref_dir = none_refdir;
std::string filename;

char* myargv[ARGS] = {NULL};
int myargc = 0;

char pwd[1024];
int lastcode = 0;


bool Check_redir(char* command)
{
    char* start = command;
    char* end = start + strlen(command);
    while(start != end)
    {
        if(*start == '>')
        {
            if(*(start+1) == '>')
            {
                ref_dir = append_refdir;
                *start = '\0';
                start += 2;
                while(*start == ' ')
                {
                    start++;
                }
                filename = start;
                break;
            }

            else 
            {
                ref_dir = output_refdir;
                *start = '\0';
                start++;
                while(*start == ' ')
                {
                    start++;
                }
                filename = start;
                break;
            }
        }

        else if(*start == '<')
        {
            ref_dir = input_refdir;
            *start = '\0';
            start++;
            while(*start == ' ')
            {
                start++;
            }
            filename = start;
            break;
        }
        start++;
    }
}



std::string GetPwd()
{
    char temp[1024] = {0};
    getcwd(temp,sizeof(temp));
    snprintf(pwd,sizeof(pwd),"PWD=%s",temp);
    putenv(pwd);

    std::string Pwd = pwd;
    size_t pos = Pwd.rfind('/');
    if(pos == std::string::npos)
    {
        return std::string("None");
    }
    std::string spwd;
    for(int i = pos+1;i<Pwd.size();i++)
    {
        spwd += Pwd[i];
    }
    return spwd;

}

void PrintCommandString()
{
    std::string username = getenv("LOGNAME");
    std::string hostname = getenv("HOSTNAME");
    std::string pwd = GetPwd();
    printf("[%s@%s %s]# ",username.c_str(),hostname.c_str(),pwd.c_str());
}


bool GetCommandString(char commandstring[],size_t len)
{
    if(commandstring == nullptr || len <= 0)
    {
        return false;
    }

    char* cmd = fgets(commandstring,len,stdin);
    if(cmd == nullptr)
        return false;
    commandstring[strlen(commandstring) - 1] = 0;
    return strlen(commandstring) == 0 ? false : true;
}



bool PraseCommandString(char commandstring[])
{
    if(commandstring == nullptr)
        return false;
    #define SEP " "
    myargv[myargc++] = strtok(commandstring,SEP);
    for(;(bool)(myargv[myargc] = strtok(NULL,SEP));myargc++);

//#define debug
#ifdef debug
    for(int i = 0;i<myargc;i++)
    {
        std:: cout << myargv[i] << std::endl; 
    }
    std::cout << myargc << std::endl;

#endif
    return true;
}

bool ForkExe()
{
    pid_t id = fork();
    if(id == 0)
    {
        if(ref_dir == output_refdir)
        {
            int fd = open(filename.c_str(),O_WRONLY|O_CREAT|O_TRUNC,0666);
            dup2(fd,1); 
        }
        else if(ref_dir == input_refdir)
        {
            int fd = open(filename.c_str(),O_RDONLY);
            dup2(fd,0);
        }
        else if(ref_dir == append_refdir)
        {
            int fd = open(filename.c_str(),O_CREAT|O_APPEND,0666);
            dup2(fd,1);
        }
        execvp(myargv[0],myargv);
        exit(0);
    }
    int x = 0;
    ref_dir = none_refdir;
    pid_t rid = waitpid(id,&x,0);
    if(rid > 0)
    {
        lastcode = WEXITSTATUS(x);
        if(lastcode == 0)
        {
            return true;
        }
        else 
        {
            return false;
        }
    }
    else{
        return false;
    }
}

bool bulitin()
{
    std::string cmd = myargv[0];
    std::string opt;
    if(cmd == "cd")
    {
        if(myargc == 1)
        {
            chdir(getenv("HOME"));
        }
        else if(myargc == 2){
            opt = myargv[1];
            chdir(opt.c_str());
        }
        return true;
    }

    else if(cmd == "echo")
    {
        if(myargc == 2)
        {
            opt = myargv[1];
            if(opt[0] == '$')
            {
                if(opt[1] == '?')
                {   
                    std::cout << lastcode << std::endl;
                    lastcode = 0;
                }
                else 
                {
                    std::string Env;
                    for(int i = 1;i<opt.size();i++)
                    {
                        Env += opt[i];
                    }

                    std::cout << getenv(Env.c_str()) << std::endl;
                }
            }
            else 
            {
                std::cout << opt << std::endl;
                if (ref_dir != none_refdir) {
                    return false;
                }
            }
            return true;
        }
    }
    return false;
}



//char commandstring[20] = {0};
//while(1)
//{
//    fgets(commandstring,20,stdin);
//}
